<?php

namespace App\Lib;

use RongCloud\RongCloud;

class RcGroupChat
{
    private static $instance = NULL;// 当前类实例

    private $rcConfig = [];// 融云配置文件
    private $rcHandle = NULL;// 融云实例

    // 定义子类 api
    protected $groupSubApi = [
        'groupBanAdd' => '/group/ban/add.json',
        'groupBanRollback' => '/group/ban/rollback.json',
        'groupBanQuery' => '/group/ban/query.json',

        'groupUserBanWhiteAdd' => '/group/user/ban/whitelist/add.json',
        'groupUserBanWhiteRollback' => '/group/user/ban/whitelist/rollback.json',
        'groupUserBanWhiteQuery' => '/group/user/ban/whitelist/query.json',
    ];

    private function __construct()
    {
        $this->rcConfig = config('rong_cloud');
        $this->rcHandle = new RongCloud($this->rcConfig['appKey'], $this->rcConfig['appSecret']);
    }

    /**
     * 返回实例
     * */
    static public function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    ############################################################################################################

    /**
     * 群组-发送消息
     *
     * @param $senderId string 发送人 Id
     * @param $targetId string 群组 Id
     * @param $objectName string 自定义消息类型
     * @param $content array 消息内容
     * @param $isIncludeSender int 发送者自己是否接收此条消息, 0: 不接收, 1: 接收, 默认: 0
     * @return bool
     * */
    public function groupSend($senderId, $targetId, $objectName, $content, $isIncludeSender = 1)
    {
        $params = [
            'senderId' => $senderId,
            'targetId' => $targetId,
            "objectName" => $objectName,
            'content' => $content,
            'isIncludeSender' => $isIncludeSender,
        ];

        $result = $this->rcHandle->getMessage()->Group()->send($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupSend', $result);
        }

        return $ret;
    }

    ############################################################################################################

    /**
     * 群组创建，每个群最多 3000 人，应用内群组数量无限制
     *
     * @param $id string 群组Id 最大长度30个字符，建议使用英文字母、数字混排
     * @param $name string 群组名称，最大长度 60 个字符
     * @param $member array 加入群组的用户列表 [['id'=>1],['id'=>2]]
     * @return bool
     * */
    public function groupCreate($id, $name, $member)
    {
        $params = [
            'id' => $id,
            'name' => $name,
            'members' => $member,
        ];

        $result = $this->rcHandle->getGroup()->create($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupCreate', $result);
        }

        return $ret;
    }

    /**
     * 获取群信息
     *
     * @param $id string 群组ID
     * @return array
     * */
    public function groupGet($id)
    {
        $params = [
            'id' => $id,
        ];

        $result = $this->rcHandle->getGroup()->get($params);

        // [
        //     "code" => 200,
        //     "members" => [
        //         ["id" => "小明"]
        //     ]
        // ];

        if ($result['code'] != 200) {
            $ret = [];
            write_log('rongcloud', '失败 群组：groupGet', $result);
        } else {
            $ret = $result['members'];
        }

        return $ret;
    }

    /**
     * 修改群信息
     *
     * @param $id string 群组ID
     * @param $name string 群组名称，最大长度 60 个字符
     * @return bool
     * */
    public function groupUpdate($id, $name)
    {
        $params = [
            'id' => $id,
            'name' => $name,
        ];

        $result = $this->rcHandle->getGroup()->update($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupUpdate', $result);
        }

        return $ret;
    }

    /**
     * 加入群组
     *
     * @param $id string 加入的群组 Id
     * @param $name string 群组名称，最大长度 60 个字符
     * @param $member array 加入群组的用户列表 ['id'=>1]
     * @return bool
     * */
    public function groupJoin($id, $name, $member)
    {
        $params = [
            'id' => $id,
            'name' => $name,
            'member' => $member,
        ];

        $result = $this->rcHandle->getGroup()->joins($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupJoin', $result);
        }

        return $ret;
    }

    /**
     * 退出群组
     *
     * @param $id string 要退出的群组 Id
     * @param $member array 要退出群组的群成员 ['id'=>1]
     * @return bool
     * */
    public function groupQuit($id, $member)
    {
        $params = [
            'id' => $id,
            'member' => $member,
        ];

        $result = $this->rcHandle->getGroup()->quit($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupQuit', $result);
        }

        return $ret;
    }

    /**
     * 解散群组
     *
     * @param $id string 被解散的群组 Id
     * @param $member array 操作解散群的用户Id ['id'=>1] （可以为任何用户Id ，非群组创建者也可以解散群组）
     * @return bool
     * */
    public function groupDismiss($id, $member)
    {
        $params = [
            'id' => $id,
            'member' => $member,
        ];

        $result = $this->rcHandle->getGroup()->dismiss($params);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupDismiss', $result);
        }

        return $ret;
    }

    ############################################################################################################

    /**
     * 融云群组 Api Header
     *
     * @param $returnJoin bool 返回拼接格式 默认true, false=返回数组key value格式
     * @return array
     * */
    protected function requestGroupHeader($returnJoin = true)
    {
        // 重置随机数种子。
        srand((double)microtime() * 1000000);

        $appKey = $this->rcConfig['appKey'] ?? ''; // 开发者平台分配的 App Key。
        $appSecret = $this->rcConfig['appSecret'] ?? ''; // 开发者平台分配的 App Secret。
        $nonce = rand(); // 获取随机数。
        $timestamp = time() * 1000; // 获取时间戳（毫秒）。
        $signature = sha1($appSecret . $nonce . $timestamp); // 签名

        $data = [
            'App-Key' => $appKey,
            'Nonce' => $nonce,
            'Timestamp' => $timestamp,
            'Signature' => $signature,
        ];

        $result = [];
        if ($returnJoin) {
            foreach ($data as $key => $value) {
                $result[] = $key . ':' . $value;
            }
        } else {
            $result = $data;
        }

        return $result;
    }

    /**
     * 群组请求参数
     *
     * @param $field string 字段
     * @param $value mixed (int/string/array) 数据值 本地支持 groupId 数字或数组或字符串拼接格式: 1 / [1,2,3] / 1,2,3
     * @param $substrLast bool 截取最后一个字符 默认true
     * @return string
     * */
    protected function requestGroupParams($field, $value, $substrLast = true)
    {
        $params = '';

        if (empty($value)) {
            return $params;
        }

        if (is_numeric($value)) {
            $value = [$value];
        } elseif (is_string($value)) {
            if (strpos($value, ',') !== false) {
                $value = array_filter(explode(',', $value));
            } else {
                $value = [$value];
            }
        }

        foreach ($value as $val) {
            $params .= $field . '=' . $val . '&';
        }

        if ($substrLast and !empty($params)) {
            $params = substr($params, 0, strlen($params) - 1);
        }

        return $params;
    }

    ############################################################################################################

    /**
     * 群组-整体禁言-添加
     *
     * @param $groupId mixed (int/string/array) 群组 Id，支持一次设置多个，最多不超过 20 个
     *
     * @return bool
     * */
    public function groupBanAdd($groupId)
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupBanAdd'];
        $requestGroupParams = $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupBanAdd', $result);
        }

        return $ret;
    }

    /**
     * 群组-整体禁言-移除
     *
     * @param $groupId mixed (int/string/array) 群组 Id，支持一次设置多个，最多不超过 20 个
     * @return bool
     * */
    public function groupBanRollback($groupId)
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupBanRollback'];
        $requestGroupParams = $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupBanRollback', $result);
        }

        return $ret;
    }

    /**
     * 群组-整体禁言-获取
     *
     * @param $groupId mixed (int/string/array) 群组 Id，不传此参数，表示查询所有设置禁言的群组列表；传此参数时，表示查询传入的群组 Id 是否被设置为群组禁言，支持一次查询多个，最多不超过 20 个
     * @return array
     * */
    public function groupBanQuery($groupId = '')
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupBanQuery'];
        $requestGroupParams = $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        //     "groupinfo" => [
        //         ["groupId" => "groupId1","stat" => 1], # stat:禁言状态，0 表示为未禁言、1 表示为禁言。
        //         ["groupId" => "groupId2","stat" => 0]
        //     ]
        // ];

        if ($result['code'] != 200) {
            $ret = [];
            write_log('rongcloud', '失败 群组：groupBanQuery', $result);
        } else {
            $ret = $result['groupinfo'];
        }

        return $ret;
    }

    ############################################################################################################


    /**
     * 群组-整体禁言-白名单-添加
     *
     * @param $userId mixed (int/string/array) 用户 Id，支持一次添加多个用户，最多不超过 20 个
     * @param $groupId mixed (int/string/array) 群组 Id
     *
     * @return bool
     * */
    public function groupUserBanWhiteAdd($userId, $groupId)
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupUserBanWhiteAdd'];
        $requestGroupParams = $this->requestGroupParams('userId', $userId, false);
        $requestGroupParams .= $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupUserBanWhiteAdd', $result);
        }

        return $ret;
    }

    /**
     * 群组-整体禁言-白名单-移除
     *
     * @param $userId mixed (int/string/array) 用户 Id，支持一次添加多个用户，最多不超过 20 个
     * @param $groupId mixed (int/string/array) 群组 Id
     * @return bool
     * */
    public function groupUserBanWhiteRollback($userId, $groupId)
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupUserBanWhiteRollback'];
        $requestGroupParams = $this->requestGroupParams('userId', $userId, false);
        $requestGroupParams .= $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        // ];

        $ret = true;
        if ($result['code'] != 200) {
            $ret = false;
            write_log('rongcloud', '失败 群组：groupUserBanWhiteRollback', $result);
        }

        return $ret;
    }

    /**
     * 群组-整体禁言-白名单-获取
     *
     * @param $groupId mixed (int/string/array) 群组 Id
     * @return array
     * */
    public function groupUserBanWhiteQuery($groupId)
    {
        $requestUrl = $this->rcConfig['apiHost'] . $this->groupSubApi['groupUserBanWhiteQuery'];
        $requestGroupParams = $this->requestGroupParams('groupId', $groupId);
        $requestGroupHeader = $this->requestGroupHeader();

        $result = curlRequest($requestUrl, $requestGroupParams, false, $requestGroupHeader);
        $result = json_decode($result, true);

        // [
        //     "code" => 200,
        //     "userIds" => [1,2]
        // ];

        if ($result['code'] != 200) {
            $ret = [];
            write_log('rongcloud', '失败 群组：groupUserBanWhiteQuery', $result);
        } else {
            $ret = $result['userIds'];
        }

        return $ret;
    }
}